<template>
  <div class="main-box">
    <TreeFilter
      :data="filterData"
      label="name"
      title="字典类型 (单选)"
      :default-value="initParam.typeId"
      @change="changeTreeFilter"
    />
    <div class="table-box">
      <ProTable
        ref="proTableRef"
        :columns="columns"
        :search-col="{ xs: 1, sm: 1, md: 2, lg: 3, xl: 3 }"
        :request-api="getDictPageApi"
        :init-param="initParam"
      >
        <!-- 表格 header 按钮 -->
        <template #tableHeader>
          <el-button v-auth="'sys:dict:add'" type="primary" :icon="CirclePlus" @click="handleAdd"> 新增字典 </el-button>
        </template>
        <!-- 分类编码 -->
        <template #code="{ row }">
          <el-tooltip effect="dark" content="点击复制" placement="top">
            <div v-copy="row.code" class="table-copy-box">
              <span>
                {{ row.code }}
              </span>
              <el-icon>
                <DocumentCopy />
              </el-icon>
            </div>
          </el-tooltip>
        </template>
        <!-- 状态 -->
        <template #isEnable="scope">
          <el-switch
            v-model="scope.row.isEnable"
            :loading="scope.row.loading"
            active-text="已启用"
            inactive-text="已禁用"
            inline-prompt
            :before-change="handleEnable.bind(scope, scope.row)"
          />
        </template>
        <!-- 表格操作 -->
        <template #operation="{ row }">
          <el-button v-auth="'sys:dict:edit'" type="primary" link :icon="EditPen" @click="handleEdit(row)"> 编辑 </el-button>
          <el-button v-auth="'sys:dict:del'" type="danger" link :icon="Delete" @click="handleDelete(row)"> 删除 </el-button>
        </template>
      </ProTable>
      <dict-edit ref="editDialogRef" />
    </div>
  </div>
</template>

<script setup lang="ts" name="dictManage">
import type { ProTableInstance, ColumnProps } from "@/components/ProTable/interface";
import type { SysDict } from "@/api/interface";
import { ref, reactive, onMounted } from "vue";
import { useHandleData } from "@/hooks/useHandleData";
import { statusConst } from "@/utils/dict";
import { CirclePlus, EditPen, Delete, DocumentCopy } from "@element-plus/icons-vue";
import {
  addDictApi,
  editDictApi,
  switchEnableDictApi,
  deleteDictApi,
  getDictTypeApi,
  getDictPageApi
} from "@/api/modules/system/dict";
import ProTable from "@/components/ProTable/index.vue";
import TreeFilter from "@/components/TreeFilter/index.vue";
import DictEdit from "./components/edit.vue";

/** 表格实例 */
const proTableRef = ref<ProTableInstance>();
/** 编辑字典弹窗实例 */
const editDialogRef = ref<InstanceType<typeof DictEdit>>();

/** 表单初始化参数 */
const initParam = reactive({ typeId: "" });
/** 字典分类数据 */
const filterData = ref<SysDict.TypeResult[]>([]);
/** 表格配置项 */
const columns = reactive<ColumnProps<SysDict.Result>[]>([
  { type: "index", label: "#", width: 80 },
  { prop: "code", label: "分类编码", align: "left" },
  { prop: "label", label: "字典标识", align: "left", search: { el: "input" } },
  { prop: "value", label: "字典值", align: "left" },
  { prop: "remarks", label: "备注说明", align: "left" },
  { prop: "sort", label: "权重(排序)", width: 100 },
  { prop: "isEnable", label: "状态", width: 100, enum: statusConst, search: { el: "select" } },
  { prop: "operation", label: "操作", width: 180, fixed: "right" }
]);

/**
 * 初始化字典分类数据
 *
 * @returns void
 */
const initFilterData = () => {
  getDictTypeApi().then(({ data }) => {
    filterData.value = data;
  });
};

/**
 * 树形筛选切换
 *
 * @param val 选中的机构id
 * @returns void
 */
const changeTreeFilter = (val: string) => {
  proTableRef.value!.pageable.pageIndex = 1;
  initParam.typeId = val;
};

/**
 * 新增字典
 *
 * @returns void
 */
const handleAdd = () => {
  const editParams = {
    title: "新增字典",
    dict: {
      dictType: 0,
      typeId: initParam.typeId || undefined,
      sort: 0
    },
    getTableList: refreshTable,
    submitApi: addDictApi
  };
  editDialogRef.value?.acceptParams(editParams);
};

/**
 * 编辑字典
 *
 * @param param 选中的字典
 * @returns void
 */
const handleEdit = (param: Partial<SysDict.Result>) => {
  const editParams = {
    title: "编辑字典",
    dict: { ...param },
    getTableList: refreshTable,
    submitApi: editDictApi
  };
  editDialogRef.value?.acceptParams(editParams);
};

/**
 * 启用/禁用字典
 *
 * @param param 选中的字典
 * @returns void
 */
const handleEnable = (param: Partial<SysDict.Result> & { loading?: boolean }) => {
  param.loading = true;
  return switchEnableDictApi({ id: param.id! })
    .then(({ data }) => {
      if (data) {
        return Promise.resolve(true);
      } else return Promise.reject(new Error("修改状态失败"));
    })
    .finally(() => {
      param.loading = false;
    });
};

/**
 * 删除字典
 *
 * @param param 选中的字典
 * @returns void
 */
const handleDelete = (param: Partial<SysDict.Result>) => {
  useHandleData(deleteDictApi, { ids: [param.id] }, `删除【${param.name}】字典`).then(res => {
    if (res) proTableRef.value?.getTableList();
  });
};

/**
 * 刷新表格数据
 *
 * @returns void
 */
const refreshTable = (refreshData: number) => {
  refreshData === 0 ? initFilterData() : proTableRef.value?.getTableList();
};

onMounted(() => {
  initFilterData();
});
</script>
